package com.nidu.demo.dept.ability;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.cola.exception.BizException;
import com.nidu.demo.common.constants.Constants;
import com.nidu.demo.common.enums.StatusEnum;
import com.nidu.demo.common.exception.ErrorCodeConstants;
import com.nidu.demo.dept.gateway.DepartmentGateway;
import com.nidu.demo.dept.model.Department;
import com.nidu.demo.user.gateway.UserDepartmentGateway;
import com.nidu.demo.user.model.UserDepartment;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Component
@RequiredArgsConstructor
public class DepartmentDomainService {

    private final DepartmentGateway gateway;

    private final UserDepartmentGateway userDepartmentGateway;

    public Department validateDept(Long id){
        Department department = gateway.getById(id);
        if (department == null) {
            throw new BizException(ErrorCodeConstants.DEPARTMENT_NOT_FOUND.getCode(),
                    ErrorCodeConstants.DEPARTMENT_NOT_FOUND.getMessage());
        }
        department.isDisable();
        department.isDeleted();
        return department;
    }

    /**
     * 检查部门编码是否重复
     * @param code 部门编码
     * @param companyId 公司Id
     * @param exculdeId 排除的Id
     */
    public void validateDuplicate(String code, Long companyId, Long exculdeId) {
        Department dept = gateway.getByCodeAndCompanyId(code, companyId);
        if(dept != null){
            if(exculdeId == null){
                throw new BizException(ErrorCodeConstants.DEPARTMENT_CODE_DUPLICATE.getCode(),
                        ErrorCodeConstants.DEPARTMENT_CODE_DUPLICATE.getMessage());
            }
            if (!exculdeId.equals(dept.getId())) {
                throw new BizException(ErrorCodeConstants.DEPARTMENT_CODE_DUPLICATE.getCode(),
                        ErrorCodeConstants.DEPARTMENT_CODE_DUPLICATE.getMessage());
            }
        }
    }

    /**
     * 检查父部门是否存在或者启用
     * @param parentId 父节点Id
     */
    public Department validateParent(Long parentId){
        if(!Constants.ROOT_DEPT_ID.equals(parentId)){
            Department parent = gateway.getById(parentId);
            if (parent == null) {
                throw new BizException(ErrorCodeConstants.DEPARTMENT_PARENT_NOT_FOUND.getCode(),
                        ErrorCodeConstants.DEPARTMENT_PARENT_NOT_FOUND.getMessage());
            }
            parent.isDisable();
            parent.isDeleted();
            return parent;
        }
        return null;
    }

    /**
     * 更新状态
     * @param deptId 部门Id
     * @param statusEnum 状态
     */
    public void updateStatus(Long deptId, StatusEnum statusEnum) {
        switch (statusEnum){
            case ENABLE:
                // 如果是子菜单，检查父菜单状态是否启用
                Department department = gateway.getById(deptId);
                validateParent(department.getParentId());
                gateway.updateStatus(deptId, StatusEnum.ENABLE.getValue());
                break;
            case DISABLE:
                // 如果是父菜单，检查子菜单状态是否禁用
                List<Department> children = gateway.getByParentId(deptId);
                validateChildren(children);
                gateway.updateStatus(deptId, StatusEnum.DISABLE.getValue());
                break;
        }
    }

    /**
     * 检查所有部门是否存在和启用
     * @param deptIds 部门Id列表
     * @return 部门
     */
    public List<Department> validateDepartmentList(Set<Long> deptIds) {
        if(!CollUtil.isEmpty(deptIds)){
            List<Department> depts = gateway.getByIds(deptIds);
            Map<Long, Integer> map = depts.stream().filter(item -> !item.getDeleted()).collect(Collectors.toMap(Department::getId, Department::getStatus));
            deptIds.forEach(id -> {
                Integer status = map.getOrDefault(id, null);
                if(status == null){
                    throw new BizException(ErrorCodeConstants.DEPARTMENT_NOT_FOUND.getCode(),
                            ErrorCodeConstants.DEPARTMENT_NOT_FOUND.getMessage());
                } else if (StatusEnum.DISABLE.getValue().equals(status)) {
                    throw new BizException(ErrorCodeConstants.DEPARTMENT_STATUS_DISABLE.getCode(),
                            ErrorCodeConstants.DEPARTMENT_STATUS_DISABLE.getMessage());
                }
            });
            return depts;
        }
        return null;
    }

    /**
     * 检查部门是否被用户使用
     * @param deptIds 部门Id列表
     */
    public void validateUserUse(Set<Long> deptIds) {
        Map<Long, List<UserDepartment>> userDepartmentMap = userDepartmentGateway.getByDeptIds(deptIds);
        if (!CollUtil.isEmpty(userDepartmentMap)) {
            throw new BizException(ErrorCodeConstants.DEPARTMENT_HAS_USER.getCode(),
                    ErrorCodeConstants.DEPARTMENT_HAS_USER.getMessage());
        }
    }

    /**
     * 检查子部门是否存在或者启用
     * @param depts 部门列表
     */
    public void validateChildren(List<Department> depts) {
        // 如果是父菜单，检查所有子菜单状态
        if (!depts.isEmpty()) {
            for (Department child : depts) {
                if (StatusEnum.ENABLE.getValue().equals(child.getStatus())) {
                    throw new BizException(ErrorCodeConstants.DEPARTMENT_HAS_CHILD.getCode(),
                            ErrorCodeConstants.DEPARTMENT_HAS_CHILD.getMessage());
                }
            }
        }
    }

}